﻿using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using CommonCodeManagers.plugin;
using Newtonsoft.Json.Linq;

namespace CommonCodeManagers
{
    public partial class BuildCode : Form
    {
        public BuildCode()
        {
            InitializeComponent();
        }

        public string TemplateContent { get; set; }

        private void txtOutputFolder_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            folderBrowserDialog.Description = "请选择输出文件夹";
            if (folderBrowserDialog.ShowDialog() == DialogResult.OK || folderBrowserDialog.ShowDialog() == DialogResult.Yes)
            {
                txtOutputFolder.Text = folderBrowserDialog.SelectedPath;
            }
        }

        private void btnBuildCode_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtJson.Text)) return;
            if (string.IsNullOrEmpty(txtTemplate.Text)) return;
            if (string.IsNullOrEmpty(txtOutputFolder.Text)) return;

            var jsonHelper = new JsonOperate(txtTemplate.Text, txtJson.Text);
            string fileContent = jsonHelper.ReplaceColumn();
            int filenameIndex = txtCsFilePath.Text.LastIndexOf("\\", StringComparison.Ordinal);
            string[] fileNamrArr = txtCsFilePath.Text.Substring(filenameIndex + 1).Split('.');
            FileOperate.WriteFile(Path.Combine(txtOutputFolder.Text, fileNamrArr[0]+ "_Generate" + "."+fileNamrArr[1]),fileContent);
            MessageBox.Show("生成成功");
        }

        private void BuildCode_Load(object sender, EventArgs e)
        {
            txtTemplate.Text = TemplateContent;
        }

        private void txtCsFilePath_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            try
            {
                LoadJson();
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
            }

        }

        private void LoadJson()
        {
            if (string.IsNullOrEmpty(txtCsFilePath.Text)) return;
            if (!File.Exists(txtCsFilePath.Text)) return;

            string classPattern = @"    /// <summary>\r\n    ///.*\r\n    /// </summary>(\r\n.*){0,10}\r\n    public( abstract){0,1} class.*?:.*",
            nemespacePattern = @"namespace .*",
            propertyPattern = @"(\r){0,1}\n.*?/// <summary>(\r){0,1}\n.*?///.*?(\r){0,1}\n.*?/// </summary>(\r\n.*?){0,1}(\r){0,1}\n.*?public .*?}",
                //propertyPattern = @"\r\n        /// <summary>\r\n        ///.*?\r\n        /// </summary>(\r\n.*?){0,1}\r\n        public .*?}",
            navigatePattern = @"\r\n        /// <summary>\r\n        ///.*?\r\n        /// </summary>(\r\n.*?){0,1}\r\n        public virtual .*?}\r\n";


            var fileContent = FileOperate.ReadFile(txtCsFilePath.Text);
            var classNameRegex = new Regex(classPattern, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            var nemespaceRegex = new Regex(nemespacePattern);
            var propertyRegex = new Regex(propertyPattern, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            var navigateRegex = new Regex(navigatePattern, RegexOptions.IgnoreCase | RegexOptions.Multiline);

            //输出的JSON
            JObject json = new JObject();

            //获取命名空间
            string strNamespace = nemespaceRegex.Match(fileContent).Value.Replace("namespace","").Replace("\r", "").Trim();
            json["Namespace"] = strNamespace;
            fileContent = nemespaceRegex.Replace(fileContent, "");


            //获取类名和名称
            string allClassInfo = classNameRegex.Match(fileContent).Value.Replace(@"    /// <summary>", "").Replace("    /// </summary>", "").Replace("\\r\\n", "");
            var labelRegex = new Regex(@"///.*");
            //获取类别注释
            string classLabel = labelRegex.Match(allClassInfo).Value.Replace("///", "").Replace("\r", "").Trim();
            //获取类别名称
            string prefixClass = "public class ";
            int classNameStartIndex = allClassInfo.IndexOf(prefixClass) + prefixClass.Length;
            int classNameLength = allClassInfo.IndexOf(":") - classNameStartIndex;
            string className = allClassInfo.Substring(classNameStartIndex, classNameLength).Trim();
            //类别继承
            string inherit = allClassInfo.Substring(allClassInfo.IndexOf(":") + 1).Replace("\r", "");
            json["ClassSummary"] = classLabel;
            json["ClassName"] = className;
            json["ClassInherit"] = inherit;

            //清除类别信息
            fileContent = classNameRegex.Replace(fileContent, "");

            //替换掉所有导航属性
            fileContent = navigateRegex.Replace(fileContent, "");


            //获取所有属性
            var properties = propertyRegex.Matches(fileContent);
            JArray jsonArray = new JArray();
            foreach (Match property in properties)
            {
                var proInfo = property.Value;
                JObject properJson = new JObject();
                proInfo = proInfo.Replace("        /// <summary>", "").Replace("        /// </summary>", "");
                properJson["PropertyLabel"] = labelRegex.Match(proInfo).Value.Replace("///", "").Replace("\r", "").Trim();

                var typeAndName = RegexValue("public .*\\{.*(get|set).*\\;.*(get|set).*\\;.*\\}", proInfo);
                typeAndName = RegexReplace("\\{.*(get|set).*\\;.*(get|set).*\\;.*\\}", typeAndName, "").TrimEnd();

                int lastIndex = typeAndName.LastIndexOf(" ");

                properJson["PropertyName"] = typeAndName.Substring(lastIndex + 1);

                typeAndName = typeAndName.Remove(lastIndex);
                lastIndex = typeAndName.LastIndexOf(" ");
                properJson["PropertyType"] = typeAndName.Substring(lastIndex + 1);
                jsonArray.Add(properJson);
            }
            json["Property"] = jsonArray;

            txtJson.Text = json.ToString();
        }

        private string RegexReplace(string pattern, string inputStr, string repStr)
        {
            var replaceRegex = new Regex(pattern);
            return replaceRegex.Replace(inputStr, repStr);
        }

        private string RegexValue(string pattern, string inputStr)
        {
            var replaceRegex = new Regex(pattern);
            return replaceRegex.Match(inputStr).Value;
        }
    }
}
